package search

import (
	"organoid_public/domain/sample"
	"organoid_public/domain/sample/repository"
	sampleService "organoid_public/domain/sample/service"
	"organoid_public/infrastructure/db/gormclient"
	"organoid_public/pkg/logger"
	"organoid_public/pkg/valueobject"
)

type service struct {
	log           logger.Logger
	sampleService sampleService.SearchServiceInterface
}

func newService(log logger.Logger) (*service, error) {
	uc, err := sample.Service()
	if err != nil {
		return nil, err
	}
	return &service{
		log:           log,
		sampleService: uc.SearchSvc,
	}, nil
}

func (s *service) GetOrganoidList(params *OrganoidListReq) (*gormclient.PageList[OrganoidListRes], error) {
	data, err := s.sampleService.OrganoidList(&repository.OrganoidListParams{
		Keywords:      params.Keywords,
		Pagination:    valueobject.NewPagination(params.Page, params.PageSize),
		Organism:      params.Organism,
		Source:        params.Source,
		Organoid:      params.Organoid,
		CoCulture:     params.CoCulture,
		CultureMethod: params.CultureMethod,
		Complexity:    params.Complexity,
	})
	if err != nil {
		return nil, err
	}
	list := make([]OrganoidListRes, 0, len(data.List))
	for _, item := range data.List {
		list = append(list, OrganoidListRes{
			SampleId:         item.SampleId,
			Organoid:         item.Organoid,
			Organism:         item.Organism,
			Source:           item.Source,
			CoCulture:        item.CoCulture,
			CoCultureDetail:  item.CoCultureDetail,
			AdditionalFactor: item.AdditionalFactor,
			Times:            item.Times,
			Method:           item.Method,
			Complexity:       item.Complexity,
			Reference:        item.Reference,
		})
	}

	return &gormclient.PageList[OrganoidListRes]{
		Page:     data.Page,
		PageSize: data.PageSize,
		Total:    data.Total,
		List:     list,
	}, nil
}

func (s *service) GetCoCultureList(params *OrganoidListReq) (*gormclient.PageList[CoCultureListRes], error) {
	data, err := s.sampleService.CoCultureList(&repository.OrganoidListParams{
		Keywords:      params.Keywords,
		Pagination:    valueobject.NewPagination(params.Page, params.PageSize),
		Organism:      params.Organism,
		Source:        params.Source,
		Organoid:      params.Organoid,
		CoCulture:     params.CoCulture,
		CultureMethod: params.CultureMethod,
		Complexity:    params.Complexity,
	})
	if err != nil {
		return nil, err
	}
	list := make([]CoCultureListRes, 0, len(data.List))
	for _, item := range data.List {
		list = append(list, CoCultureListRes{
			SampleId:         item.SampleId,
			Organoid:         item.Organoid,
			Times:            item.Times,
			CoCulture:        item.CoCulture,
			Medium:           item.Medium,
			ReadOut:          item.ReadOut,
			AdditionalFactor: item.AdditionalFactor,
			Reference:        item.Reference,
		})
	}

	return &gormclient.PageList[CoCultureListRes]{
		Page:     data.Page,
		PageSize: data.PageSize,
		Total:    data.Total,
		List:     list,
	}, nil
}

func (s *service) GetBioMarkerIdentifyList(params *BiomarkerListReq) (*gormclient.PageList[IdentifyListRes], error) {
	data, err := s.sampleService.IdentifyList(&repository.BiomarkerListParams{
		Keywords:               params.Keywords,
		Pagination:             valueobject.NewPagination(params.Page, params.PageSize),
		Organism:               params.Organism,
		Source:                 params.Source,
		Organoid:               params.Organoid,
		Period:                 params.Period,
		BiomarkerClassfication: params.BiomarkerClassfication,
		DetectionMethod:        params.DetectionMethod,
		CoCulture:              params.CoCulture,
		DiseaseModeling:        params.DiseaseModeling,
		DrugTest:               params.DrugTest,
	})
	if err != nil {
		return nil, err
	}
	list := make([]IdentifyListRes, 0, len(data.List))
	for _, item := range data.List {
		list = append(list, IdentifyListRes{
			SampleId:                item.SampleId,
			Organoid:                item.Organoid,
			Organism:                item.Organism,
			Source:                  item.Source,
			Method:                  item.DetectionMethod,
			Model:                   item.Model,
			ModelDetail:             item.ModelDetail,
			BiomarkerOrganoid:       item.BiomarkerOrganoid,
			BiomarkerOrganoidDetail: item.BiomarkerOrganoidDetail,
			BiomarkerModel:          item.BiomarkerModel,
			BiomarkerModelDetail:    item.BiomarkerModelDetail,
			ReadOut:                 item.ReadOut,
			Reference:               item.Reference,
		})
	}

	return &gormclient.PageList[IdentifyListRes]{
		Page:     data.Page,
		PageSize: data.PageSize,
		Total:    data.Total,
		List:     list,
	}, nil
}

func (s *service) GetBioMarkerPotentialList(params *BiomarkerListReq) (*gormclient.PageList[PotentialListRes], error) {
	data, err := s.sampleService.PotentialList(&repository.BiomarkerListParams{
		Keywords:               params.Keywords,
		Pagination:             valueobject.NewPagination(params.Page, params.PageSize),
		Organism:               params.Organism,
		Source:                 params.Source,
		Organoid:               params.Organoid,
		Period:                 params.Period,
		BiomarkerClassfication: params.BiomarkerClassfication,
		DetectionMethod:        params.DetectionMethod,
		CoCulture:              params.CoCulture,
		DiseaseModeling:        params.DiseaseModeling,
		DrugTest:               params.DrugTest,
	})
	if err != nil {
		return nil, err
	}
	list := make([]PotentialListRes, 0, len(data.List))
	for _, item := range data.List {
		list = append(list, PotentialListRes{
			SampleId:                           item.SampleId,
			Organoid:                           item.Organoid,
			Organism:                           item.Organism,
			PotentialBiomarker:                 item.PotentialBiomarker,
			ExperimentalStrategyRnaSeq:         item.ExperimentalStrategyRnaSeq,
			ExperimentalStrategyRnaSeqDetail:   item.ExperimentalStrategyRnaSeqDetail,
			ExperimentalStrategyScrnaSeq:       item.ExperimentalStrategyScrnaSeq,
			ExperimentalStrategyScrnaSeqDetail: item.ExperimentalStrategyScrnaSeqDetail,
			Application:                        item.Application,
			Verification:                       item.Verification,
		})
	}

	return &gormclient.PageList[PotentialListRes]{
		Page:     data.Page,
		PageSize: data.PageSize,
		Total:    data.Total,
		List:     list,
	}, nil
}
